<template>
    <div class="mike_body">
        <div class="mike_left">
            <div class="chat">

            </div>
            <div class="chatBottom">
                <div :class="{mike_volume:true, mike_volume_a:volume > 0}">
                    <div :class="{mike_volume_val:true, mike_volume_val_bg: volume == 0}" :style="{height:volume > 0 ? volume*2+4+'%' : '100%'}"></div>
                </div>
                <button 
                    @click="stateFun" 
                    :class="{mike_button:true, mike_button_red:this.isRecording}">
                    {{ this.isRecording ? '停止' : '开始' }}
                </button>
                
            </div>
            
        </div>
        <div class="mike_right">
            <div class="waveList">
                <ul class="waveList_ul">
                    <li  class="waveList_ul_li animate__animated animate__bounceInDown" v-for="(item, index) in waveList" :key="index">
                        <div :id="'waveList_' + index" :key="index" class="wave"></div>
                        <div class="wave_buttons">
                            <span>{{ item.currentTime ? item.currentTime : '00' }} / {{ item.time }}</span>
                            <el-button @click="togglePlay(index,  item.isPlaying)" size="small" style="margin-left: auto;">
                                {{ item.isPlaying ? '暂停' : '播放' }}
                            </el-button>
                        </div>
                        
                        <!-- <div>
                            <audio controls="controls" class="audioDom">
                                <source :src="item.url" type="audio/mp3" />
                                <source :src="item.url" type="audio/ogg" />
                                <embed height="60" :src="item.url" />
                            </audio>
                        </div> -->
                    </li>
                </ul>
            </div>
        </div>
    </div>
</template>

<script>
import RecordRTC from 'recordrtc'; 
import WaveSurfer from 'wavesurfer.js'; // 音波
const uploadFileUrl = ref(import.meta.env.VITE_APP_BASE_API + "/file/upload"); // 上传文件服务器地址

export default{
    name: "mike",
    data() {
      return {
        stream: null, // 用于存储从用户麦克风获取的媒体流
        recorder: null, // 用于存储RecordRTC实例
        wavesurfer: null, // 用于存储WaveSurfer实例 波浪实例
        audioBlob: null, // 存储录音的Blob对象
        waveList: [], // 
        volume: 0, // 音量

        list:[],

        intervalId: null,  // 定时器ID
        isRecording: false,  // 是否正在录制
      };
    },
    mounted() {
        // 初始化WaveSurfer实例
        /* this.wavesurfer = WaveSurfer.create({
            container: '#idddddddddddddd_div', // 指定波形图的DOM容器
            waveColor: '#67C23A', // 波形的颜色
            progressColor: 'purple' // 播放进度颜色
        }); */
    },
    created(){
        this.fun();
    },
    methods: {
        fun(){
            console.log('123');
        },
        // 会议录制
        stateFun(){
            if (!this.isRecording) {
                this.isRecording = true;
                this.mikeFun(); // 开始第一次录制
                this.intervalId = setInterval(() => {
                    this.mikeFun();  // 每9秒执行一次录制
                }, 3000);
            } else {
                clearInterval(this.intervalId);  // 清除定时器
                this.isRecording = false;
                this.stopMike(); // 停止录制
            };
        },
        // 录制方法
        /* async mikeFun(){
            if(!this.stream){ //是否在录音
                try{
                    this.stream = await navigator.mediaDevices.getUserMedia({ audio: true });  //获取 麦克风权限
                    this.recorder = new RecordRTC(this.stream, {  //实例 录制音频
                        type: 'audio',
                    });
                    this.recorder.startRecording(); // 开始录制
                    console.log('录音开始...');
                }catch(err){
                    proxy.$modal.msgError("获取麦克风权限失败");
                    console.log("获取麦克风权限失败", err);
                }
            }else{
                this.stopMike();
            };
        }, */
        async mikeFun() {
            if (!this.stream) { // 检查是否已经在录音
                try {
                    this.stream = await navigator.mediaDevices.getUserMedia({ audio: true }); //获取 麦克风权限
                    this.recorder = new RecordRTC(this.stream, { //实例 录制音频
                        type: 'audio', //指定录制音频，不包括视频
                    });

                    const audioContext = new AudioContext(); // 创建一个新的AudioContext对象，它代表了由音频模块处理、控制和连接的虚拟的音频处理图
                    const source = audioContext.createMediaStreamSource(this.stream); // 将获取到的媒体流连接到AudioContext，以便可以对流中的音频数据进行操作
                    const analyser = audioContext.createAnalyser(); // 创建一个AnalyserNode，用于实时获取音频信号的频率和时间域的数据
                    analyser.fftSize = 2048; // 设置FFT（快速傅里叶变换）的大小，影响分析的精度和数据量
                    source.connect(analyser);  // 将音频源连接到分析器，分析器可以提取音频流的数据进行实时分析
                    this.monitorVolume(analyser, volume => { // 调用monitorVolume函数，并传入一个回调处理实时音量
                        console.log('实时音量:', volume);
                        this.volume = volume;
                    });

                    this.recorder.startRecording();  // 开始录制
                    console.log('录音开始...');
                } catch (err) {
                    proxy.$modal.msgError("获取麦克风权限失败");
                    console.log("获取麦克风权限失败", err);
                }
            } else {
                this.stopMike();
            }
        },
        // 实时音量
        monitorVolume(analyser, callback) {
            const bufferLength = analyser.frequencyBinCount; // 从analyser中获取buffer的长度
            const dataArray = new Uint8Array(bufferLength); // 创建一个数组来存储音频数据

            const trackVolume = () => {
                analyser.getByteTimeDomainData(dataArray); // 获取当前的时域音频数据
                let sum = 0;
                for (let i = 0; i < bufferLength; i++) {
                    const x = dataArray[i] / 128.0 - 1; // 数据归一化处理
                    sum += x * x;
                }
                const rms = Math.sqrt(sum / bufferLength); // 计算均方根值作为音量
                const volume = Math.max(rms, 0.01); // 防止音量值为零

                const scaledVolume = Math.min(volume * 100, 100); // 将音量从0-1映射到0-100
                //const val = Math.round(scaledVolume); // 将音量四舍五入到最近的整数
                const val = parseFloat(scaledVolume.toFixed(1)); // 格式化音量到小数点后一位，并转换为浮点数

                callback(val); // 使用回调函数返回音量

                requestAnimationFrame(trackVolume); // 持续监控音量
            };

            trackVolume(); // 启动音量监控循环
        },
        // 暂停
        stopMike(){
            this.recorder.stopRecording(()=>{
                this.audioBlob = this.recorder.getBlob(); // 获取音频数据
                let newUrl = URL.createObjectURL(this.audioBlob); // url

                let leng = this.waveList.length;
                this.waveList.push({
                    id: leng,
                    wavesurfer: null,
                    url: newUrl,
                    isPlaying: false,  // 新增属性来跟踪播放状态
                    time: null,
                    currentTime: null,
                });
                this.$nextTick(()=>{
                    let num = this.waveList.length - 1;
                    let newWaveSurfer = WaveSurfer.create({
                        container: '#waveList_' + num,
                        waveColor: '#fff',
                        progressColor: '#409EFF',
                        cursorColor: '#E6A23C',
                        height: 36,
                        fillParent: true,
                    });
                    newWaveSurfer.loadBlob(this.audioBlob);

                    // 当 WaveSurfer 完全加载并准备好音频时触发
                    newWaveSurfer.on('ready', () => {
                        let totalTime = newWaveSurfer.getDuration(); // 获取音频总时长
                        this.waveList[num].time = totalTime; // 存储总时长
                        console.log(`音频总时长: ${totalTime.toFixed(2)}秒`);
                    });

                    // 添加事件监听器以处理音频播放过程中的更新
                    newWaveSurfer.on('audioprocess', () => {
                        let currentTime = newWaveSurfer.getCurrentTime(); // 获取当前播放时间
                        this.waveList[num].currentTime = currentTime.toFixed(2); // 更新当前播放时间
                        console.log(`当前播放时间: ${currentTime.toFixed(2)}秒`);
                    });

                    // 当音频播放结束时，重置播放头或重新加载音频
                    newWaveSurfer.on('finish', ()=>{
                        newWaveSurfer.seekTo(0); // 或者 newWaveSurfer.loadBlob(this.audioBlob);
                        this.waveList[num].isPlaying = false;
                    });
                    this.waveList[num].wavesurfer = newWaveSurfer;
                });

                // 停止媒体流，释放麦克风
                this.stream.getAudioTracks().forEach(track => track.stop());
                this.stream = null;

                // 调用上传文件的方法
                this.uploadAudio(this.audioBlob, leng);
            }); 
        },
        // 播放
        togglePlay(index, isPlaying) {
            console.log(isPlaying);
            // 首先暂停所有波形图的播放
            this.waveList.forEach((item) => {
                    item.wavesurfer.pause();
                    item.isPlaying = false;
            });
            let item = this.waveList[index];
            this.$nextTick(()=>{
                if (!isPlaying) {
                    if (item.wavesurfer.isPlaying()) {
                        item.wavesurfer.pause();
                        item.isPlaying = false;  // 更新播放状态为暂停
                    } else {
                        item.wavesurfer.play();
                        item.isPlaying = true;   // 更新播放状态为播放
                    }
                };
            });
            
        },
        // 定义上传文件的方法
        uploadAudio(blob, leng) {
            const formData = new FormData();
            formData.append("file", blob, "name_" + leng + ".mp3"); // 添加音频文件到表单数据

            fetch(uploadFileUrl.value, { // 确保 uploadFileUrl 是正确的后端接口URL
                method: 'POST',
                body: formData,
            })
            .then(response => response.json())
            .then(data => {
                console.log('文件上传成功:', data);
            })
            .catch(error => {
                console.error('上传失败:', error);
            });
        },
    },
    beforeDestroy() {
        if (this.intervalId) {
            clearInterval(this.intervalId);
        }
        this.waveList.forEach(item => {
            if (item.wavesurfer) {
                item.wavesurfer.destroy();
            }
        });
    },
    components:{
    },
}
</script>

<style setup lang='scss'>
.mike_body{
    display: flex;
    box-sizing: border-box;
    height: calc(100vh - 50px);
    > div{
        display: flex;
        flex-direction: column;
        box-sizing: border-box;
    }
    .mike_left{
        flex-grow: 1;
        display: flex;
        flex-direction: column;
        box-sizing: border-box;
        padding: 10px;
        .chat{
            flex-grow: 1;
            overflow-y: auto;
        }
        .chatBottom{
            display: flex;
            flex-direction: row-reverse;
            box-sizing: border-box;
            padding: 5px;
            border:solid 1px #409EFF;
            border-radius: 5px;
            gap: 10px;
            .mike_volume{
                height: 100%;
                width: 20px;
                border: solid 1px #999;
                padding: 2px;
                border-radius: 4px;
                display: flex;
                flex-direction: column-reverse;
                .mike_volume_val{
                    background: #67C23A;
                    border-radius: 2px;
                    max-height: 100%;
                }
                .mike_volume_val_bg{
                    background: #ccc;
                }
            }
            .mike_volume_a{
                border-color:#67C23A;
            }
        }
    }   
    .mike_right{
        width: 500px;
        display: flex;
        flex-direction: column;
        box-shadow: 0px 0px 10px 1px rgba(0,0,0,0.2);
        padding: 10px;
        box-sizing: border-box;
        .waveList{
            display: flex;
            flex-direction: column;
            flex-grow: 1;
            overflow-y: auto;
            overflow-x: hidden;
            scroll-padding-bottom: 0px;
            .waveList_ul{
                display: flex;
                flex-direction:column-reverse;
                flex-grow: 1;
                gap: 5px;
                padding-bottom: 1px;
                box-sizing: border-box;
                .waveList_ul_li{
                    box-sizing: border-box;
                    padding: 10px;
                    border:solid 1px #409EFF;
                    border-radius: 5px;
                    display: flex;
                    flex-direction: column;
                    gap: 5px;
                    .wave{
                        border-radius: 5px;
                        background: #409EFF;
                        padding: 10px;
                        box-sizing: border-box;
                    }
                    .wave_buttons{
                        display: flex;
                        gap: 10px;
                        align-items: center;
                        span{
                            color: #999;
                            font-size: 14px;
                            padding: 0 2px;
                        }
                    }
                }
            }
        }
    }
    .mike_button{
        width: 60px;
        height: 60px;
        color: #fff;
        border-radius: 50px;
        border:solid 1px #409EFF;
        background: linear-gradient(140deg, #60b0ff, #409EFF 70%, #51a8ff,  #91c8ff);
        font-weight: bold;
    }
    .mike_button_red{
        background: linear-gradient(140deg, #ff7d7d, #F56C6C 70%, #ff5b5b,  #ff7e7e);
        box-shadow: 0 0 5px 5px rgb(245, 108, 108, 0.5);
        border:solid 1px #F56C6C;
        animation-name:mike_button_red_flash;
        animation-duration:0.5s; /* 规定动画完成一个周期所花费的秒或毫秒 */
        animation-timing-function:linear; /* 规定动画的速度曲线。默认是 "ease" */
        animation-delay:0s; /* 规定动画何时开始。默认是 0 */
        animation-iteration-count:infinite; /* 规定动画被播放的次数。默认是 1 */
        animation-play-state:running; /* 规定动画是否正在运行或暂停。默认是 "running" */
        animation-direction:alternate; /* 规定动画是否在下一周期逆向地播放。默认是 "normal" */
    }
    @keyframes mike_button_red_flash
    {
        0%  {box-shadow: 0 0 3px 0 rgb(245, 108, 108, 0.5);}
        100%  {box-shadow: 0 0 5px 5px rgb(245, 108, 108, 0.5);}
    }
    .audioDom{
        width: 100%;
        height: 20px;
    }
}

.hasTagsView {
    .mike_body{
        height: calc(100vh - 84px);
    }
}
</style>
<style lang='scss'>
</style>